package com.coursebooking.repository;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.coursebooking.model.Booking;
import com.coursebooking.model.Course;
import com.coursebooking.model.Student;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.util.List;
import java.util.Optional;

@Mapper
public interface BookingRepository extends BaseMapper<Booking> {
    
    @Select("SELECT * FROM booking WHERE student_id = #{studentId} AND course_id = #{courseId}")
    Booking selectByStudentAndCourse(@Param("studentId") Long studentId, @Param("courseId") Long courseId);
    
    @Select("SELECT * FROM booking WHERE student_id = #{studentId}")
    List<Booking> selectByStudentId(Long studentId);
    
    @Select("SELECT * FROM booking WHERE course_id = #{courseId}")
    List<Booking> selectByCourseId(Long courseId);
    
    @Select("SELECT * FROM booking WHERE status = #{status}")
    List<Booking> selectByStatus(String status);
    
    @Select("SELECT COUNT(*) FROM booking WHERE course_id = #{courseId} AND status = 'CONFIRMED'")
    long countConfirmedBookingsByCourseId(@Param("courseId") Long courseId);
    
    @Select("SELECT COUNT(*) FROM booking WHERE student_id = #{studentId} AND course_id = #{courseId} AND status != 'CANCELLED'")
    int countByStudentAndCourse(@Param("studentId") Long studentId, @Param("courseId") Long courseId);
    
    // 为了保持兼容性，添加包装方法
    default Optional<Booking> findByStudentAndCourse(Student student, Course course) {
        return Optional.ofNullable(selectByStudentAndCourse(student.getId(), course.getId()));
    }
    
    default List<Booking> findByStudent(Student student) {
        return selectByStudentId(student.getId());
    }
    
    default List<Booking> findByCourse(Course course) {
        return selectByCourseId(course.getId());
    }
    
    default List<Booking> findByStatus(Booking.BookingStatus status) {
        return selectByStatus(status.name());
    }
    
    default long countConfirmedBookingsByCourse(Course course) {
        return countConfirmedBookingsByCourseId(course.getId());
    }
    
    default boolean existsByStudentAndCourse(Student student, Course course) {
        return countByStudentAndCourse(student.getId(), course.getId()) > 0;
    }
}